﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using NetCoreBBS.Infrastructure;
using NetCoreBBS.Entities;
using NetCoreBBS.Interfaces;
using NetCoreBBS.ViewModels;
using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Identity;
using System.Security.Claims;
using Microsoft.EntityFrameworkCore;
using static NetCoreBBS.Common.Enums;

// For more information on enabling MVC for empty projects, visit http://go.microsoft.com/fwlink/?LinkID=397860

namespace NetCoreBBS.Controllers
{
    [Route("[controller]")]
    public class TopicController : Controller
    {
        private readonly ITopicRepository _topic;
        private readonly IRepository<TopicNode> _node;
        private readonly ITopicReplyRepository _reply;
        private readonly IUserServices _user;
        private readonly UserManager<ApplicationUser> _userManager;
        private readonly IRepository<Department> _departmentRepository;

        public TopicController(ITopicRepository topic,
            IRepository<TopicNode> node,
            ITopicReplyRepository reply,
            IUserServices user,
            UserManager<ApplicationUser> userManager,
            IRepository<Department> departmentRepository)
        {
            _topic = topic;
            _node = node;
            _reply = reply;
            _user = user;
            _userManager = userManager;
            _departmentRepository = departmentRepository;
        }

        [Route("[action]/{nodeId}/{departmentId?}")]
        public async Task<IActionResult> Index(int nodeId, int? departmentId = 0)
        {
            ViewBag.NodeId = nodeId;
            await BuildDepartmentList();
            var node = _node.GetById(nodeId);
            if (node == null) return Redirect("/");
            ViewBag.NodeName = node.Name;
            var pagesize = 20;
            var pageindex = 1;
            Page<Topic> result;
            if (!string.IsNullOrEmpty(Request.Query["page"]))
                pageindex = Convert.ToInt32(Request.Query["page"]);
            var currentUser = _user.User.Result;

            if (!string.IsNullOrEmpty(Request.Query["s"]))
            {
                result = _topic.PageList(r => r.NodeId == node.Id && r.Title.Contains(Request.Query["s"]), pagesize, pageindex);
            }
            else
            {
                result = _topic.PageList(r => r.NodeId == node.Id, pagesize, pageindex);
            }

            ViewBag.Topics = result.List.Select(r => new TopicViewModel
            {
                Id = r.Id,
                NodeId = r.Node.Id,
                NodeName = r.Node.Name,
                UserName = r.User.UserName,
                Avatar = r.User.Avatar,
                Title = r.Title,
                Top = r.Top,
                Type = r.Type,
                ReplyCount = r.ReplyCount,
                LastReplyTime = r.LastReplyTime,
                CreateOn = r.CreateTime
            }).ToList();
            ViewBag.PageIndex = pageindex;
            ViewBag.PageCount = result.GetPageCount();
            ViewBag.Node = node;
            ViewBag.Count = result.Total;
            return View();
        }

        [Route("[action]")]
        public async Task<IActionResult> Search(string s)
        {
            var pagesize = 20;
            var pageindex = 1;
            Page<Topic> result = new Page<Topic>(new List<Topic>(), pagesize, pageindex);
            if (!string.IsNullOrEmpty(Request.Query["page"]))
                pageindex = Convert.ToInt32(Request.Query["page"]);
            var currentUser = _user.User.Result;
            bool isAdminOrSuperman = false;
            var claims = await _userManager.GetClaimsAsync(currentUser);
            foreach (var c in claims)
            {
                if (c.Type == ClaimTypes.Role && c.Value == "Admin" || c.Type == ClaimTypes.Role && c.Value == "Superman")
                {
                    isAdminOrSuperman = true;
                    break;
                }
            }
            ViewBag.IsAdminOrSuperman = isAdminOrSuperman;
            if (isAdminOrSuperman)
            {
                    if (!string.IsNullOrEmpty(Request.Query["s"]))
                        result = _topic.PageList(x => x.Title.Contains(Request.Query["s"]), pagesize, pageindex);           
            }
            else
            {
                if (!string.IsNullOrEmpty(Request.Query["s"]))
                {
                    result = _topic.PageList(x => (x.DepartmentId == currentUser.DepartmentId || x.NodeId == 11) && x.Title.Contains(Request.Query["s"]), pagesize, pageindex);
                }
            }
            ViewBag.Topics = result.List.Select(r => new TopicViewModel
            {
                Id = r.Id,
                NodeId = r.Node.Id,
                NodeName = r.Node.Name,
                UserName = r.User.UserName,
                Avatar = r.User.Avatar,
                Title = r.Title,
                Top = r.Top,
                Type = r.Type,
                ReplyCount = r.ReplyCount,
                LastReplyTime = r.LastReplyTime,
                CreateOn = r.CreateTime
            }).ToList();
            ViewBag.PageIndex = pageindex;
            ViewBag.PageCount = result.GetPageCount();
            ViewBag.Count = result.Total;
            return View();
        }


        // GET: /Topic/1
        [Route("[action]/{id}")]
        public IActionResult Details(string node, int id)
        {
            if (id <= 0) return Redirect("/");
            var topic = _topic.GetById(id);
            if (topic == null) return Redirect("/");
            var replys = _reply.List(r => r.TopicId == id).ToList();
            topic.ViewCount += 1;
            _topic.Edit(topic);
            ViewBag.Replys = replys;
            return View(topic);
        }
        [HttpPost]
        [ValidateAntiForgeryToken]
        [Route("[action]/{id}")]
        public IActionResult Details([Bind("TopicId,ReplyUserId,ReplyEmail,ReplyContent")]TopicReply reply)
        {
            if (ModelState.IsValid&&!string.IsNullOrEmpty(reply.ReplyContent))
            {
                reply.CreateOn = DateTime.Now;
                _reply.Add(reply);
                var topic = _topic.GetById(reply.TopicId);
                topic.LastReplyUserId = reply.ReplyUserId;
                topic.LastReplyTime = reply.CreateOn;
                topic.ReplyCount += 1;
                _topic.Edit(topic);
            }
            return RedirectToAction("Details", "Topic", new { Id = reply.TopicId });
        }

        [Route("[action]/{nodeId}/{id?}")]
        public IActionResult CreateOrUpdate(int nodeId, int? id)
        {
            ViewBag.User = _user.User.Result;
            //var nodes = _node.List().ToList();
            //ViewBag.NodeListItem = nodes.Where(r => r.ParentId != 0).Select(r => new SelectListItem { Value = r.Id.ToString(), Text = r.Name });
            var node = _node.GetById(nodeId);
            ViewBag.NodeId = node.Id;
            ViewBag.NodeName = node.Name;
            if (id != null)
            {
                var topic = _topic.GetById(id.Value);
                if (topic == null) return Redirect("/");
                var replys = _reply.List(r => r.TopicId == id).ToList();
                topic.ViewCount += 1;
                _topic.Edit(topic);
                ViewBag.Replys = replys;
                return View(topic);
            }
            return View();
        }

        [HttpPost]
        [ValidateAntiForgeryToken]
        [Route("[action]/{nodeId}/{id?}")]
        public IActionResult CreateOrUpdate(int nodeId, int? id, Topic topic)
        {
            if (ModelState.IsValid)
            {
                //var node = _node.GetById(nodeId);
                //ViewBag.NodeName = node.Name;

                if (id == null)
                {
                    topic.CreateTime = DateTime.Now;
                    topic.Type = TopicType.Normal;
                    _topic.Add(topic);
                }
                else
                {
                    _topic.Edit(topic);
                }
            }
            return RedirectToAction(nameof(Index), "Home");
        }

        #region help

        private async Task BuildDepartmentList(object selected = null)
        {
            var list = await _departmentRepository.TableNoTracking.ToListAsync();

            ViewBag.DepartmentList = new SelectList(list, "Id", "Name", selected);
        }
        #endregion

    }
}
